<template>
	<el-drawer
	  v-model="dialog.visible"
	  :title="dialog.title"
	  append-to-body
	  @close="closeDialog"
	  :close-on-click-modal="false"
	  size="750"
	>
		<el-scrollbar>
		<el-form
			ref="formRef"
			:model="formData"
			:rules="formRules"
			label-width="180px"
		>
			<el-form-item label="输入字段" prop="inputFieldIdentifier">
				<el-select v-model="formData.inputFieldIdentifier"   placeholder="请选择输入字段名" >
					<el-option
					  v-for="item in standardFields"
					  :key="item.outputFieldIdentifier"
					  :label="item.outputFieldName"
					  :value="item.outputFieldIdentifier"
					  @click="handleInputFieldSelect(item)"
					/>
				</el-select>
			</el-form-item>
			
			<el-form-item label="输入字段类型" prop="inputFieldType"  >
				<Dict v-model="formData.inputFieldType" code="field_type" disabled />
			</el-form-item>
			
			<el-form-item label="输入字段格式" prop="inputFieldFormat" v-if="['dateString'].includes(formData.inputFieldType)">
				<el-input v-model="formData.inputFieldFormat" placeholder="请输入输入格式" readonly />
			</el-form-item>
			
			<el-form-item label="输入字段值映射输出" prop="inputFieldValueMapping" >
				<el-select v-model="formData.inputFieldValueMapping" disabled >
					<el-option label="none" value="none" />
					<el-option label="Sql" value="sql" />
					<el-option label="Redis" value="redis" />
					<el-option label="HTTP" value="http" />
				</el-select>
			</el-form-item>
			
			<el-form-item label="字段值映射对象" prop="inputFieldValueMappingObject" v-if="formData.inputFieldValueMapping!='none'" >
				<el-select v-model="formData.inputFieldValueMappingObject" disabled >
					<el-option label="none" value="none" />
					<el-option label="Sql" value="sql" />
					<el-option label="Redis" value="redis" />
					<el-option label="HTTP" value="http" />
				</el-select>
			</el-form-item>
			
			<el-form-item label="输入输出字段名相同" prop="sameFieldName">
				<el-radio-group v-model="formData.sameFieldName" @change="handleSameFieldNameChange">
				  <el-radio :value="'0'">不同</el-radio>
				  <el-radio :value="'1'">相同</el-radio>
				</el-radio-group>
			</el-form-item>
			
			<el-form-item label="输出字段名" prop="outputFieldName">
				<el-input 
					v-model="formData.outputFieldName" 
					placeholder="请输入输出字段名" 
					:readonly="formData.sameFieldName === '1'"
				/>
			</el-form-item>
			
			<el-form-item label="输入输出字段标识相同" prop="sameFieldIdentifier">
				<el-radio-group v-model="formData.sameFieldIdentifier" @change="handleSameFieldIdentifierChange">
				  <el-radio :value="'0'">不同</el-radio>
				  <el-radio :value="'1'">相同</el-radio>
				</el-radio-group>
			</el-form-item>
			
			<el-form-item label="输出字段标识" prop="outputFieldIdentifier">
				<el-input 
					v-model="formData.outputFieldIdentifier" 
					placeholder="请输入输出字段标识" 
					:readonly="formData.sameFieldIdentifier === '1'"
				/>
			</el-form-item>
			
			<el-form-item label="输出字段类型" prop="outputFieldType" required >
				<Dict v-model="formData.outputFieldType" code="field_type" style="width: 100%;" />
			</el-form-item>
			
			<el-form-item label="输出时序库存储类型" prop="outputValueStorageType"  v-if="showStorageTypeField==true">
				<el-radio-group v-model="formData.outputValueStorageType" >
					<el-radio value="field">字段</el-radio>
					<el-radio value="tag" >标签</el-radio>
					<el-radio value="time" >时间戳</el-radio>
				</el-radio-group>
			</el-form-item>
			
			<el-form-item label="输出日期格式定义" prop="outputFieldDateFormatSrc" v-if="['dateString'].includes(formData.outputFieldType)">
				<el-radio-group v-model="formData.outputFieldDateFormatSrc" class="flex-container">
					<el-radio value="input">自定义</el-radio>
					<el-radio value="select">下拉选择日期格式</el-radio>
				</el-radio-group>
			</el-form-item>
			
			<el-form-item label="输出字段格式" prop="outputFieldFormat" v-if="['dateString'].includes(formData.outputFieldType)">
				<template v-if="formData.outputFieldDateFormatSrc === 'select'">
					<el-select v-model="formData.outputFieldFormat" placeholder="请选择输出日期格式">
						<el-option label="yyyy-MM-dd" value="yyyy-MM-dd" />
						<el-option label="yyyy-MM-dd HH:mm:ss" value="yyyy-MM-dd HH:mm:ss" />
						<el-option label="yyyy年MM月dd日" value="yyyy年MM月dd日" />
						<el-option label="yyyy年MM月dd日 HH时mm分ss秒" value="yyyy年MM月dd日 HH时mm分ss秒" />
						<el-option label="HH:mm:ss" value="HH:mm:ss" />
						<el-option label="HH时mm分ss秒" value="HH时mm分ss秒" />
						<el-option label="yyyy/MM/dd" value="yyyy/MM/dd" />
						<el-option label="yyyy/MM/dd HH:mm:ss" value="yyyy/MM/dd HH:mm:ss" />
						<el-option label="yyyyMMdd" value="yyyyMMdd" />
						<el-option label="yyyyMMddHHmmss" value="yyyyMMddHHmmss" />
					</el-select>
				</template>
				<template v-else>
					<el-input v-model="formData.outputFieldFormat" placeholder="请输入自定义日期格式" />
				</template>
			</el-form-item>
			
			<el-form-item label="输出字段保留小数位" prop="outputFieldDecimalPoint" v-if="['float','double'].includes(formData.outputFieldType)">
				<el-input-number v-model="formData.outputFieldDecimalPoint" placeholder="请输入字段保留小数位" :min="0" :max="32" />
			</el-form-item>
			
			<el-form-item label="输出字段值来源" prop="outputValueFromInput">
				<el-select v-model="formData.outputValueFromInput">
					<el-option label="输入值" value="input" />
					<el-option label="常量值" value="constant" />
					<el-option label="系统时间" value="curSystemDate" />
					<el-option label="OLTP" value="OLTP" />
					<el-option label="缓存(Redis)" value="redis" />
					<el-option label="uuid" value="uuid" />
				</el-select>
			</el-form-item>
			
			<!-- OLTP数据库相关配置 -->
			<template v-if="formData.outputValueFromInput === 'OLTP'">
				<el-form-item label="数据源" prop="outputValueDatasourceId">
					<el-select v-model="formData.outputValueDatasourceId" placeholder="请选择数据源">
						<el-option
						  v-for="item in datasourceOptions"
						  :key="item.id"
						  :label="item.name"
						  :value="item.id"
						/>
					</el-select>
				</el-form-item>
				
<!-- 				<el-form-item label="SQL语句" prop="outputValueSql">
					<el-input
						v-model="formData.outputValueSql"
						type="textarea"
						:rows="3"
						placeholder="请输入SQL语句，可使用#{value}引用输入值"
					/>
				</el-form-item> -->
				
				<el-form-item label="输出字段取值SQL" prop="outputValueSql">
					<div style="display: flex;flex-direction: column;width: 100%;">
						<MonacoEditor
						  v-model="formData.outputValueSql"
						  :options="sqlEditorOptions"
						  language="sql"
						  style="height: 200px;"
						  @change="validateSQL"
						/>
						
						<div class="sql-tips">
						  <el-alert
							title="SQL编写提示"
							type="info"
							:closable="false"
						  >
							<template #default>
							  <p>1. SQL语句支持以SELECT、Delete、Update等</p>
							  <p>2. SQL必须包含参数标识字段: {{ formData.outputFieldIdentifier?.split('.').pop() }}</p>
							  <p>3. 查询结果的字段名必须与参数标识字段匹配</p>
							  <p>4. 如果输入字段为sql参数，编写sql示例:( field=${输入字段标识})</p>
							</template>
						  </el-alert>
						</div>
					</div>
				</el-form-item>
				
				
			</template>
			
			<!-- Redis缓存相关配置 -->
			<template v-if="formData.outputValueFromInput === 'redis'">
				<el-form-item label="Redis键" prop="outputValueRedisKey">
					<el-input v-model="formData.outputValueRedisKey" placeholder="请输入Redis键" />
				</el-form-item>
			</template>
			
			<el-form-item label="输出字段默认值" prop="outputFieldDefaultValue">
				<el-input 
					v-model="formData.outputFieldDefaultValue" 
					:placeholder="formData.outputValueFromInput === 'constant' ? '请输入常量值' : '请输入输出字段默认值'"
				/>
			</el-form-item>
		</el-form>
		</el-scrollbar>
		<template #footer>
		  <div class="dialog-footer">
			<el-button type="primary" @click="submitForm" :loading="loading">确 定</el-button>
			<el-button @click="closeDialog" :loading="loading">取 消</el-button>
		  </div>
		</template>
	</el-drawer>
</template>

<script lang="ts" setup>
	import { ref } from "vue";
	import type {FormRules } from 'element-plus'
	import { ElMessage } from "element-plus";
	import { reactive } from "vue";
	import { onMounted, watch } from "vue";
	import MonacoEditor from '@/components/MonacoEditor/index.vue'
	import DatasourceAPI from '@/api/biz/datasource';
	const emit = defineEmits(['success', 'closed']);
	const loading = ref(false);
	const dialog = ref({
		visible:false,
		title:'',
	});
	const rowIndex = ref<number>(1);
	const formRef=ref();
	const formRules=reactive<FormRules>({
		inputFieldName: [
			{ required: true, message: "请输入输入字段名", trigger: "blur" },
			{ min: 2, max: 50, message: "长度在 2 到 50 个字符", trigger: "blur" }
		],
		inputFieldIdentifier: [
			{ required: true, message: "请输入输入字段标识", trigger: "blur" },
			{ pattern: /^[a-zA-Z][a-zA-Z0-9_]*$/, message: "标识符必须以字母开头，只能包含字母、数字和下划线", trigger: "blur" }
		],
		inputFieldType: [
			{ required: true, message: "请选择输入字段类型", trigger: "change" }
		],
		inputFieldFormat: [
			{ required: true, message: "请选择输入字段值格式", trigger: "change" }
		],
		inputFieldValueMapping: [
			{ required: true, message: "请选择输入字段值映射输出", trigger: "change" }
		],
		inputFieldValueMappingObject: [
			{ 
				required: true, 
				message: "请选择字段值映射对象", 
				trigger: "change",
				validator: (_rule: any, value: string) => {
					if (formData.value.inputFieldValueMapping !== 'none' && (!value || value === 'none')) {
						return new Error('请选择字段值映射对象');
					}
					return true;
				}
			}
		],
		sameFieldName: [
			{ required: true, message: "请选择是否字段名相同", trigger: "change" }
		],
		outputFieldName: [
			{ required: true, message: "请输入输出字段名", trigger: "blur" },
			{ min: 2, max: 50, message: "长度在 2 到 50 个字符", trigger: "blur" }
		],
		sameFieldIdentifier: [
			{ required: true, message: "请选择是否字段标识相同", trigger: "change" }
		],
		outputFieldIdentifier: [
			{ required: true, message: "请输入输出字段标识", trigger: "blur" },
			{ pattern: /^[a-zA-Z][a-zA-Z0-9_]*$/, message: "标识符必须以字母开头，只能包含字母、数字和下划线", trigger: "blur" }
		],
		outputFieldType: [
			{ required: true, message: "请选择输出字段类型", trigger: "change" }
		],
		outputFieldFormat: [
			{ required: true, message: "请选择输出字段格式", trigger: "change" }
		],
		outputFieldDecimalPoint: [
			{ required: true, message: "请输入输出字段保留小数位", trigger: "change" }
		],
		outputValueFromInput: [
			{ required: true, message: "请选择输出取值输入", trigger: "change" }
		],
		outputValueDatasourceId: [
			{ required: true, message: '请选择数据源', trigger: 'change' }
		],
		outputValueSql: [
			{ required: true, message: '请输入SQL语句', trigger: 'blur' }
		],
		outputValueRedisKey: [
			{ required: true, message: '请输入Redis键', trigger: 'blur' }
		],
		outputValueStorageType: [
			{ required: true, message: '请选择时序库存储类型', trigger: 'blur' }
		],
		outputFieldDefaultValue: [
			{ 
				required: true,
				message: "请输入常量值",
				trigger: "blur",
				validator: (_rule: any, value: string) => {
					if (formData.value.outputValueFromInput === 'constant' && !value) {
						return new Error('当输出值来源为常量值时，必须输入常量值');
					}
					return true;
				}
			}
		]
	});
	
	//数据源
	const formData=ref<any>({
		outputFieldDateFormatSrc: 'select',
		oltpDatasources: []
	});
	
	
	const sqlEditorOptions = {
	  theme: 'vs-dark',
	  language: 'sql',
	  automaticLayout: true,
	  minimap: { enabled: false },
	  lineNumbers: 'on',
	  folding: true,
	  wordWrap: 'on',
	  fontSize: 14,
	  tabSize: 2,
	  formatOnPaste: true,
	  formatOnType: true,
	  suggestOnTriggerCharacters: true,
	  quickSuggestions: true,
	};
	
	const standardFields=ref<any>();
	
	// 获取OLTP数据源列表
	const datasourceOptions=ref<any>([]);
	
	const getOLTPDatasources= async ()=>{
		try {
			const data = await DatasourceAPI.options({});
			datasourceOptions.value = data.map((item:any) => ({
				id: item.id,
				name: item.name
			}));
		} catch (error:any) {
			console.error(error)
			ElMessage.error('获取OLTP下拉数据失败');
		}
	}
	
	const validateSQL = (_rule: any, value: string | undefined, callback: any): void => {
	  if ((!value || value.trim() === '') && formData.value.outputValueFromInput === 'OLTP') {
	    callback(new Error('请输入SQL语句'));
	    return;
	  }
	  
	  if (value && formData.value.outputValueFromInput === 'OLTP') {
	    // 检查是否包含参数标识字段
	    const identifier = formData.value.outputFieldIdentifier;
	    const columnName = identifier.split('.').pop(); // 获取最后一段作为字段名
	    
	    // SQL 必须以 SELECT 开头
	    // if (!value.trim().toLowerCase().startsWith('select')) {
	    //   callback(new Error('SQL语句必须以SELECT开头'));
	    //   return;
	    // }
	    
	    // 检查是否包含参数标识字段
	    const hasIdentifier = value.toLowerCase().includes(columnName.toLowerCase());
	    if (!hasIdentifier) {
	      callback(new Error(`SQL语句必须包含参数标识字段: ${columnName}`));
	      return;
	    }
	  }
	  callback();
	};
	
	const showStorageTypeField=ref<boolean>();
	async function openDialog(index: number,_row?: any,standards?:any, type?: string,storageType?:boolean) {
		if('add'==type){
			rowIndex.value=index;
			dialog.value.visible=true;
			dialog.value.title='新增字段';
			showStorageTypeField.value=storageType||false;
			standardFields.value=standards;
		}else{
			rowIndex.value=index;
			dialog.value.visible=true;
			dialog.value.title='编辑字段';
			showStorageTypeField.value=storageType||false;
			formData.value=JSON.parse(JSON.stringify(_row));
			standardFields.value=standards;
		}
		await getOLTPDatasources();
	}
	
	const submitForm=()=>{
		formRef.value.validate((isValid: boolean) => {
			if (isValid) {
				loading.value = true;
				emit('success', rowIndex.value, JSON.parse(JSON.stringify(formData.value)));
				loading.value = false;
				closeDialog();
			}
		});
	}
	
	const closeDialog=()=>{
		dialog.value.visible=false;
		dialog.value.title="";
		emit('closed')
		resetForm();
	}
	
	/**
	 * 重置表单
	 */
	function resetForm() {
		formRef.value.resetFields();
		formRef.value.clearValidate();
		formData.value={};
	}	
	
	defineExpose({
	  openDialog,closeDialog
	});
	
	onMounted(() => {
	});
	
	// 监听输入字段标识的变化
	watch(() => formData.value.inputFieldIdentifier, (newVal) => {
		if (newVal) {
			const selectedField = standardFields.value.find(
				(item: any) => item.outputFieldIdentifier === newVal
			);
			if (selectedField) {
				handleInputFieldSelect(selectedField);
			}
		}
	});
	
	// 处理输入字段选择
	const handleInputFieldSelect = (field: any) => {
		// 填充输入字段信息
		formData.value.inputFieldName = field.outputFieldName;
		formData.value.inputFieldType = field.outputFieldType;
		formData.value.inputFieldFormat = field.outputFieldFormat || '';
		formData.value.inputFieldValueMapping = field.outputFieldValueMapping || 'none';
		formData.value.inputFieldValueMappingObject = field.outputFieldValueMappingObject || 'none';
		
		// 设置默认的字段名和标识符相同性
		formData.value.sameFieldName = formData.value?.sameFieldName || '1';
		formData.value.sameFieldIdentifier = formData.value?.sameFieldIdentifier ||'1';
		
		// 填充输出字段信息（默认与输入相同）
		
		if(formData.value.sameFieldName=='1'){
			formData.value.outputFieldName = field.outputFieldName;
		}else{
			formData.value.outputFieldName = formData.value?.outputFieldName || ""  ;
		}
		
		if(formData.value.outputFieldIdentifier=='1'){
			formData.value.outputFieldIdentifier = field.outputFieldIdentifier;
		}else{
			formData.value.outputFieldIdentifier = formData.value?.outputFieldIdentifier || ""  ;
		}
		
		if(formData.value.outputFieldIdentifier=='1'){
			formData.value.outputFieldIdentifier = field.outputFieldIdentifier;
		}else{
			formData.value.outputFieldIdentifier = formData.value?.outputFieldIdentifier || ""  ;
		}
		
		formData.value.outputFieldType = formData.value?.outputFieldType || field.outputFieldType;
		formData.value.outputFieldFormat = formData.value?.outputFieldFormat || '';
		formData.value.outputFieldDefaultValue = formData.value?.outputFieldDefaultValue || '';
		formData.value.outputValueFromInput = formData.value?.outputValueFromInput || 'input';
	};
	
	// 处理字段名相同性变化
	const handleSameFieldNameChange = (value: any) => {
		if (value === '1') {
			// 如果选择相同，则输出字段名与输入字段名保持一致
			formData.value.outputFieldName = formData.value.inputFieldName;
		}
	};
	
	// 处理字段标识相同性变化
	const handleSameFieldIdentifierChange = (value: any) => {
		if (value === '1') {
			// 如果选择相同，则输出字段标识与输入字段标识保持一致
			formData.value.outputFieldIdentifier = formData.value.inputFieldIdentifier;
		}
	};
	
	// 监听输入字段名变化
	watch(() => formData.value.inputFieldName, (newVal) => {
		if (formData.value.sameFieldName === '1') {
			formData.value.outputFieldName = newVal;
		}
	});
	
	// 监听输入字段标识变化
	watch(() => formData.value.inputFieldIdentifier, (newVal) => {
		if (formData.value.sameFieldIdentifier === '1') {
			formData.value.outputFieldIdentifier = newVal;
		}
	});
	
	// 监听输出值来源变化
	watch(() => formData.value.outputValueFromInput, (newVal) => {
		// 当切换到常量值时，清空默认值
		if (newVal === 'constant') {
		//	formData.value.outputFieldDefaultValue = '';
		}
		// 触发表单验证
		if (formRef.value) {
			formRef.value.validateField('outputFieldDefaultValue');
		}
	});
</script>

<style scoped>
	.step-content{
		background-color: aliceblue;
		margin-top: 8px;
		padding: 8px;
		padding-top: 16px;
	}
</style>